home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65c+IDA-1.4.4.1 / support / syslog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-01-19  |  4.9 KB  |  203 lines

  1. /*
  2.  * Copyright (c) 1983, 1988 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #if defined(LIBC_SCCS) && !defined(lint)
  19. static char sccsid[] = "@(#)syslog.c    5.20 (Berkeley) 1/19/89";
  20. #endif /* LIBC_SCCS and not lint */
  21.  
  22. /*
  23.  * SYSLOG -- print message on log file
  24.  *
  25.  * This routine looks a lot like printf, except that it outputs to the
  26.  * log file instead of the standard output.  Also:
  27.  *    adds a timestamp,
  28.  *    prints the module name in front of the message,
  29.  *    has some other formatting types (or will sometime),
  30.  *    adds a newline on the end of the message.
  31.  *
  32.  * The output of this routine is intended to be read by syslogd(8).
  33.  *
  34.  * Author: Eric Allman
  35.  * Modified to use UNIX domain IPC by Ralph Campbell
  36.  */
  37.  
  38. #include <sys/types.h>
  39. #include <sys/socket.h>
  40. #include <sys/file.h>
  41. #include <sys/signal.h>
  42. #include <sys/syslog.h>
  43. #include <netdb.h>
  44. #include <strings.h>
  45. #include <varargs.h>
  46. #include <stdio.h>
  47.  
  48. #define    LOGNAME    "/dev/log"
  49. #define    CONSOLE    "/dev/console"
  50.  
  51. static int    LogFile = -1;        /* fd for log */
  52. static int    connected;        /* have done connect */
  53. static int    LogStat = 0;        /* status bits, set by openlog() */
  54. static char    *LogTag = "syslog";    /* string to tag the entry with */
  55. static int    LogFacility = LOG_USER;    /* default facility code */
  56.  
  57. syslog(pri, fmt, args)
  58.     int pri, args;
  59.     char *fmt;
  60. {
  61.     vsyslog(pri, fmt, &args);
  62. }
  63.  
  64. vsyslog(pri, fmt, ap)
  65.     int pri;
  66.     register char *fmt;
  67.     va_list ap;
  68. {
  69.     extern int errno;
  70.     register int cnt;
  71.     register char *p;
  72.     time_t now, time();
  73.     int pid, saved_errno;
  74.     char tbuf[2048], fmt_cpy[1024], *ctime();
  75.  
  76.     saved_errno = errno;
  77.  
  78.     /* see if we should just throw out this message */
  79.     if ((u_int)LOG_FAC(pri) >= LOG_NFACILITIES ||
  80.         !LOG_MASK(LOG_PRI(pri)) || (pri &~ (LOG_PRIMASK|LOG_FACMASK)))
  81.         return;
  82.     if (LogFile < 0 || !connected)
  83.         openlog(LogTag, LogStat | LOG_NDELAY, 0);
  84.  
  85.     /* set default facility if none specified */
  86.     if ((pri & LOG_FACMASK) == 0)
  87.         pri |= LogFacility;
  88.  
  89.     /* build the message */
  90.     (void)time(&now);
  91.     (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4);
  92.     for (p = tbuf; *p; ++p);
  93.     if (LogTag) {
  94.         (void)strcpy(p, LogTag);
  95.         for (; *p; ++p);
  96.     }
  97.     if (LogStat & LOG_PID) {
  98.         (void)sprintf(p, "[%d]", getpid());
  99.         for (; *p; ++p);
  100.     }
  101.     if (LogTag) {
  102.         *p++ = ':';
  103.         *p++ = ' ';
  104.     }
  105.  
  106.     /* substitute error message for %m */
  107.     {
  108.         register char ch, *t1, *t2;
  109.         char *strerror();
  110.  
  111.         for (t1 = fmt_cpy; ch = *fmt; ++fmt)
  112.             if (ch == '%' && fmt[1] == 'm') {
  113.                 ++fmt;
  114.                 for (t2 = strerror(saved_errno);
  115.                     *t1 = *t2++; ++t1);
  116.             }
  117.             else
  118.                 *t1++ = ch;
  119.         *t1 = '\0';
  120.     }
  121.  
  122.     (void)vsprintf(p, fmt_cpy, ap);
  123.  
  124.     /* output the message to the local logger */
  125.     if (send(LogFile, tbuf, cnt = strlen(tbuf), 0) >= 0 ||
  126.         !(LogStat&LOG_CONS))
  127.         return;
  128.  
  129.     /* output the message to the console */
  130.     pid = vfork();
  131.     if (pid == -1)
  132.         return;
  133.     if (pid == 0) {
  134.         int fd;
  135.         long sigsetmask();
  136.  
  137.         (void)signal(SIGALRM, SIG_DFL);
  138.         sigsetmask((long)~sigmask(SIGALRM));
  139.         (void)alarm((u_int)5);
  140.         if ((fd = open(CONSOLE, O_WRONLY, 0)) < 0)
  141.             return;
  142.         (void)alarm((u_int)0);
  143.         (void)strcat(tbuf, "\r");
  144.         p = index(tbuf, '>') + 1;
  145.         (void)write(fd, p, cnt + 1 - (p - tbuf));
  146.         (void)close(fd);
  147.         _exit(0);
  148.     }
  149.     if (!(LogStat & LOG_NOWAIT))
  150.         while ((cnt = wait((int *)0)) > 0 && cnt != pid);
  151. }
  152.  
  153. static struct sockaddr SyslogAddr;    /* AF_UNIX address of local logger */
  154. /*
  155.  * OPENLOG -- open system log
  156.  */
  157. openlog(ident, logstat, logfac)
  158.     char *ident;
  159.     int logstat, logfac;
  160. {
  161.     if (ident != NULL)
  162.         LogTag = ident;
  163.     LogStat = logstat;
  164.     if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
  165.         LogFacility = logfac;
  166.     if (LogFile == -1) {
  167.         SyslogAddr.sa_family = AF_UNIX;
  168.         strncpy(SyslogAddr.sa_data, LOGNAME, sizeof SyslogAddr.sa_data);
  169.         if (LogStat & LOG_NDELAY) {
  170.             LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
  171.             fcntl(LogFile, F_SETFD, 1);
  172.         }
  173.     }
  174.     if (LogFile != -1 && !connected &&
  175.         connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) != -1)
  176.         connected = 1;
  177. }
  178.  
  179. /*
  180.  * CLOSELOG -- close the system log
  181.  */
  182. closelog()
  183. {
  184.     (void) close(LogFile);
  185.     LogFile = -1;
  186.     connected = 0;
  187. }
  188.  
  189. static int    LogMask = 0xff;        /* mask of priorities to be logged */
  190. /*
  191.  * SETLOGMASK -- set the log mask level
  192.  */
  193. setlogmask(pmask)
  194.     int pmask;
  195. {
  196.     int omask;
  197.  
  198.     omask = LogMask;
  199.     if (pmask != 0)
  200.         LogMask = pmask;
  201.     return (omask);
  202. }
  203.